package id.mankel.commons.security.session;

/**
 * An interface of session manager.
 * @author Mankel
 */
public interface SessionManager<S> {

    // TODO 安全措施：token 与 IP 绑定，每次请求都校验token和IP（或者其它特征值），在登录时就要拿到当时的特征值
    /**
     * Generates a token for this session.
     * @param subject session subject, e.g.: user info
     * @return unique token for this session
     */
    String generateToken(Object subject);

    /**
     * Returns current subject.
     * @return current subject
     */
    S getCurrentSubject();

    /**
     * Returns current subject id.
     * @return current subject id
     */
    Integer getCurrentSubjectId();

    /**
     * Binds an object to this session, using the name specified.
     * @param name the name to which the object id bound
     * @param value the object to be bound
     */
    void setAttribute(String name, Object value);

    /**
     * Returns the object bound with the name specified in this session, of null if no object is bound under the name.
     * @param name the name of the object
     * @return the object with the specified name
     */
    Object getAttribute(String name);

    /**
     * Returns the object bound with the name specified in this session, of null if no object is bound under the name.
     * @param name the name of the object
     * @param tClass class type to which the object is cast
     * @param <T> class type to which the object is cast
     * @return the object with the specified name
     */
    default <T> T getAttribute(String name, Class<T> tClass) {
        return (T) this.getAttribute(name);
    }

    /**
     * Removes the object bound with the specified name in this session.
     * @param name the name of the object
     */
    void removeAttribute(String name);

    /**
     * Reset the timeout of this session.
     */
    void resetTimeout();

    /**
     * Invalidates this session then unbinds any objects bound to it.
     */
    void invalidate();

    /**
     * Returns true if current session is valid.
     * @return true if current session is valid
     */
    boolean isValid();

}
